package com.iteaj.iot.simulator.dtu;

import com.iteaj.iot.Message;
import com.iteaj.iot.SocketMessage;
import com.iteaj.iot.client.ClientConnectProperties;
import com.iteaj.iot.client.TcpSocketClient;
import com.iteaj.iot.client.codec.SimpleChannelInboundClient;
import com.iteaj.iot.client.component.TcpClientComponent;
import com.iteaj.iot.consts.MessageFormat;
import com.iteaj.iot.simulator.SimulatorException;
import com.iteaj.iot.utils.ByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.internal.StringUtil;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

public class SimulatorDtuClient extends TcpSocketClient {

    public SimulatorDtuClient(TcpClientComponent clientComponent, SimulatorDtuConnectProperties config) {
        super(clientComponent, config);
    }

    @Override
    protected ChannelInboundHandler createProtocolDecoder() {

        return new SimpleChannelInboundHandler<ByteBuf>(false) {
            @Override
            protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
                SocketMessage socketMessage = SimulatorDtuClient.this.getClientComponent().proxy(ctx, msg);
                if(socketMessage != null) {
                    ctx.fireChannelRead(socketMessage);
                }
            }

            @Override
            public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
                super.userEventTriggered(ctx, evt);
                if(evt instanceof IdleStateEvent) {
                    // 发送心跳包
                    ctx.writeAndFlush(Unpooled.wrappedBuffer(getBytes(getConfig().getHeartbeatMsg())));
                }
            }
        };
    }

    @Override
    protected void doInitChannel(Channel channel) {
        super.doInitChannel(channel);
        // 需要发送心跳包
        if(getConfig().isHeartbeat()) {
            if(getConfig().getInterval() > 0 && !StringUtil.isNullOrEmpty(getConfig().getHeartbeatMsg())) {
                getConfig().setAllIdleTime(getConfig().getInterval());

                // 增加连接是否闲置的监听
                channel.pipeline().addFirst(new IdleStateHandler(getConfig().getReaderIdleTime()
                        , getConfig().getWriterIdleTime(), getConfig().getAllIdleTime(), TimeUnit.SECONDS));
            } else {
                logger.error("模拟器(DTU) 发送心跳包失败 - 间隔: {} - 心跳包: {}"
                        , getConfig().getInterval(), getConfig().getHeartbeatMsg());
            }
        }
    }

    @Override
    protected void successCallback(ChannelFuture future) {
        super.successCallback(future);
        // 需要发送注册包
        if(getConfig().isRegister()) {
            if(!StringUtil.isNullOrEmpty(getConfig().getDeviceSn())) {
                this.writeAndFlush(Unpooled.wrappedBuffer(getBytes(getConfig().getDeviceSn())));
            } else {
                logger.error("模拟器(DTU) 发送注册包失败 - 报文: {}"
                        , getClientComponent().getName(), getConfig().getDeviceSn());
            }
        }
    }

    protected byte[] getBytes(String msg) {
        MessageFormat format = getConfig().getFormat();
        if(format == MessageFormat.Hex) {
            return ByteUtil.hexToByte(msg);
        } else if(format == MessageFormat.Ascii) {
            return msg.getBytes(StandardCharsets.US_ASCII);
        } else if(format == MessageFormat.Utf8) {
            return msg.getBytes(StandardCharsets.UTF_8);
        } else {
            logger.error("模拟器(DTU) 不支持的报文格式 - 格式: {} - 报文: {}"
                    , getClientComponent().getName(), getConfig().getFormat(), msg);
            return Message.EMPTY;
        }
    }

    @Override
    public SimulatorDtuConnectProperties getConfig() {
        return (SimulatorDtuConnectProperties) super.getConfig();
    }
}
